#define _USE_MATH_DEFINES // ��� C++
#include <cmath>
#include "Circle.h"
#include <iostream>
#include <fstream>

//constructor: point - radius
Circle::Circle(const Point& point, const double radius, colour col)
	:Shape(col), center(point), m_radius(radius) {};

//constructor: coordinate of point - radius 
Circle::Circle(const double x, const double y, const double radius, colour col)
	:Shape(col), center(x, y), m_radius(radius) {}; 

//copy-constructor
Circle::Circle(const Circle& other)
	:Shape(other)//���������������� ������� �����
{
	center = other.center;
	m_radius = other.m_radius;
}

//����������� ��������� ����������
//Circle::Circle(const Rect& rect) :Shape(rect), center(rect.GetCenter())
//{
//	int tmp_left, tmp_right, tmp_top, tmp_bottom;
//	rect.GetAll(tmp_left, tmp_right, tmp_top, tmp_bottom);
//	
//	if ((tmp_right - tmp_left) < (tmp_bottom - tmp_top))
//	{
//		m_radius = (tmp_right - tmp_left) / 2;
//	}
//	else { m_radius = (tmp_bottom - tmp_top) / 2; }
//}

Circle::~Circle()
{
	//???
}

Shape& Circle::operator=(const Shape& other)
{
	//if (dynamic_cast<Circle*>(const_cast<Shape*>(&other)))//if ref �� bad_cast() ���������� �������������
	//{
	//	*this = static_cast<const Circle&>(other);
	//	return *this;
	//}
	//else throw std::bad_cast();
	return *this = dynamic_cast<const Circle&>(other);//if ref �� bad_cast() ���������� �������������
}

bool Circle::operator==(const Shape& other) const
{
	const Circle* p = dynamic_cast<Circle*>(const_cast<Shape*>(&other));
	if (p) {
		//return Shape::operator==(*p) && center == p->center && m_radius == p->m_radius;//���� �� ���������� �������� ���������
		return *this == *p;
	}
	return false;
}

bool Circle::operator==(const Circle& other) const
{
	if (center == other.center && m_radius == other.m_radius)
	{
		return true;
	}

	return false;
}

Shape* Circle::CopyObj() const
{
	return new Circle(*this);
}

double Circle::Get_area() const
{
	return M_PI * m_radius * m_radius;
}

const Point& Circle::Get_center() const
{
	return center;
}

double Circle::Get_distance() const
{
	double x, y;
	center.GetAll(x, y);
	double dis = abs(x * x) + abs(y * y);

	return sqrt(dis);
}
 
//void Circle::Inflate(int inflate)
//{
//	m_radius += inflate / 2;
//}
 
std::ostream& operator<<(std::ostream& os, const Circle& circle)
{
	os << static_cast<const Shape&>(circle);
	os << "distance: "<<circle.Get_distance() << " ";
	os << "area: "<< circle.Get_area() << " ";
	os << circle.center << " radius: " << circle.m_radius;
	return os;
}

Circle& operator>>(std::ifstream& is, Circle& circle)
{
	char  buff[20];
	size_t m_colour;
	static colour arr[]{ RED, GREEN, BLUE, BLACK };
	is >> buff >> m_colour;
	circle.m_colour = arr[m_colour];
	is >> buff >> buff >> buff >> buff;
	is >> circle.center;
	is >> buff >> circle.m_radius;

	return circle;
}
